package other.xsy.passlys.account;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.ScheduleJob;
import com.rkhd.platform.sdk.api.annotations.*;
import com.rkhd.platform.sdk.data.model.Account;
import com.rkhd.platform.sdk.data.model.SyncConfig__c;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.AsyncTaskException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.http.RkhdHttpClient;
import com.rkhd.platform.sdk.http.RkhdHttpData;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.param.ScheduleJobParam;
import com.rkhd.platform.sdk.service.FutureTaskService;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.task.FutureTask;
import org.apache.commons.lang.StringUtils;
import other.xsy.passlys.util.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 定时批量调整客户的所属区域公海
 * @Author 黎炎松
 * 2024-07-05 11:24
 */
@RestApi(baseUrl = "/xsy/account")
public class BatchUpAccountRegionSchedule implements ScheduleJob, FutureTask {

    private static HCXObjectService hcxObjectService = new HCXObjectService();
    private static final Logger logger = LoggerFactory.getLogger();
    private static String LOGGER_MSG = "定时批量调整客户的所属区域公海 ==> ";

    // 执行定时任务
    @Override
    public void execute(ScheduleJobParam scheduleJobParam) {
        logger.debug(LOGGER_MSG + " 执行定时任务开始");
        try {
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), "");
            logger.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (Exception e) {
            logger.error(LOGGER_MSG + " ----- 发生异常：" + e.getMessage());
        }
    }

    // 执行异步函数
    @Override
    public void execute(String s) throws ScriptBusinessException {
        batchUpAccountRegion();
    }

    /**
     * 回写模块审批日志、状态信息
     * @return
     */
    @RestMapping(value = "/batchUpAccountRegion", method = RequestMethod.POST)
    public String batchUpAccountRegionApi() throws AsyncTaskException {
        String messageId = FutureTaskService.instance().addFutureTask(getClass(), "");
        logger.info(LOGGER_MSG + "异步ID:" + messageId);
        return TfReturnMsgTools.getSuccessResult("开始处理");
    }

    public static void main(String[] args) throws Exception {
        BatchUpAccountRegionSchedule batchUpAccountRegionSchedule = new BatchUpAccountRegionSchedule();
        batchUpAccountRegionSchedule.batchUpAccountRegion();

    }

    public void dealData() throws ApiEntityServiceException {
        String sql = String.format("select id,accountName,territoryHighSeaId.name as name,ownerId.dimDepart.mrghfz__c mrghfz from account where territoryHighSeaStatus in (1,2,11) order by updatedAt desc limit 18000,21000");
        List<JSONObject> accountList = XoqlService.instance().query(sql).getRecords();
        System.out.println("accountList = " + accountList.size());
        List<Account> upList = new ArrayList<>();
        for (JSONObject account : accountList) {
            String name = account.getString("name");
            String mrghfz = getOptionStr(account.getJSONArray("mrghfz"));
            if (!Objects.equals(name, mrghfz)) {
                Account upAccount = new Account();
                upAccount.setId(account.getLong("id"));
                upList.add(upAccount);
            }
            if (upList.size() > 100) {
                System.out.println("更新====");
                hcxObjectService.batchUpdate(upList);
                upList.clear();
            }
        }
        System.out.println("upList = " + upList.size());
        if (upList.size() > 0) {
            hcxObjectService.batchUpdate(upList);
        }
    }


    public String getOptionStr(JSONArray optionArr) {
        String optStr = "";
        if (optionArr != null && optionArr.size() > 0) {
            optStr = optionArr.stream().map(v -> v.toString()).collect(Collectors.joining(","));
        }
        return optStr;
    }

    /**
     * 批量处理 定时批量调整客户的所属区域公海
     */
    public void batchUpAccountRegion() {
        try {
            logger.info(LOGGER_MSG + "处理开始");

            // 从数据配置表中获取上次更新时间
            String sql = "select id,lastSyncTime__c from syncConfig__c where syncKey__c = 'UP_ACCOUNT_REGION'";
            SyncConfig__c syncConfig = hcxObjectService.queryOne(sql, SyncConfig__c.class);
            if (syncConfig == null) {
                logger.info(LOGGER_MSG + "配置信息不存在");
                return;
            }

            // 获取同步时间
            String startDate = syncConfig.getLastSyncTime__c();
            Long endDateLong = System.currentTimeMillis(); // 同步结束时间
            // 如果为空则退回1天前
            if (StringUtils.isBlank(startDate)) {
                startDate = HCDateUtils.getDaysBeforeString(1, HCDateUtils.FORMATTIME);
            }
            logger.info(LOGGER_MSG + "startDate:" + startDate);
            long startDateLong = HCDateUtils.stringToLong(startDate, HCDateUtils.FORMATTIME);

            // 查询修改时间范围内的数据
            sql = String.format("select id,territoryHighSeaId,ownerId.dimDepart.mrghfz__c mrghfz from account where territoryHighSeaStatus in (1,2,11) and updatedAt between %s and %s", startDateLong, endDateLong);
            logger.info(LOGGER_MSG + "sql:" + sql);
            List<JSONObject> accountList = hcxObjectService.batchXoqlQuery(sql);
            logger.info(LOGGER_MSG + "accountRecords:" + accountList.size());
            if (accountList.size() <= 0) {
                logger.debug(LOGGER_MSG + "无需要处理的数据");
                syncConfig.setLastSyncCount__c(0L);
                syncConfig.setLastSyncTime__c(HCDateUtils.longToString(endDateLong, HCDateUtils.FORMATTIME));
                hcxObjectService.update(syncConfig);
                return;
            }

            // 获取部门的所属区域公海值
            Long upCount = 0L;
            JSONArray pickList = HcUtils.getGlobalPicks("globalPick97__c");
            for (JSONObject account : accountList) {
                Integer mrghfz = account.getInteger("mrghfz");
                if (mrghfz == null || mrghfz <= 0) {
                    logger.info(LOGGER_MSG + "当前部门没有绑定公海池分组");
                    continue;
                }

                // 判断是否需要修改
                String optionApiKey = HcUtils.getOptionApi(pickList, mrghfz);
                String territoryHighSeaId = account.getString("territoryHighSeaId");
                if (optionApiKey != null && Objects.equals(territoryHighSeaId, optionApiKey)) {
                    logger.info(LOGGER_MSG + "所属区域公海无需修改");
                    continue;
                }

                // 修改所属区域公海
                Long id = account.getLong("id");
                JSONObject upAccount = new JSONObject();
                upAccount.put("objectApiKey", "account");
                Long[] ids = {id};
                upAccount.put("ids", ids);
                upAccount.put("targetHighSeaId", optionApiKey);
                updateAccountRegion(upAccount);
                upCount++;
            }

            // 更新配置表时间
            syncConfig.setLastSyncCount__c(upCount);
            syncConfig.setLastSyncTime__c(HCDateUtils.longToString(endDateLong, HCDateUtils.FORMATTIME));
            hcxObjectService.update(syncConfig);

            logger.info(LOGGER_MSG + "处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(LOGGER_MSG + "处理异常:" + e.getMessage());
        }
    }


    /**
     * 修改客户所属公海区域
     * @param jsonObject
     * @throws Exception
     */
    public void updateAccountRegion(JSONObject jsonObject) throws Exception {
        RkhdHttpClient httpClient = new RkhdHttpClient();
        RkhdHttpData data  = RkhdHttpData.newBuilder()
                .callType("PUT")
                .callString("/rest/data/v2.0/xobjects/territory/actions/change")
                .body(jsonObject.toJSONString())
                .build();
        String execute = httpClient.execute(data, e -> e);
        logger.info("更新结果：" + execute);
        JSONObject result = JSONObject.parseObject(execute);
        String msg = result.getString("msg");
        if(result.getInteger("code") != 200 && !Objects.equals("OK", msg)) {
            logger.error("修改客户所属公海区域异常: " + msg);
            //throw new RuntimeException(result.getString("msg"));
        }
    }
}
